home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- *
- * sa2dkb.c
- *
- * from DKBTrace (c) 1990 David Buck
- *
- * This program reads a Sculpt-Animate 3D format scene file and generates an
- * output file that may be read in to DKBTrace.
- *
- *
- * This software is freely distributable. The source and/or object code may be
- * copied or uploaded to communications services so long as this notice remains
- * at the top of each file. If any changes are made to the program, you must
- * clearly indicate in the documentation and in the programs startup message
- * who it was who made the changes. The documentation should also describe what
- * those changes were. This software may not be included in whole or in
- * part into any commercial package without the express written consent of the
- * author. It may, however, be included in other public domain or freely
- * distributed software so long as the proper credit for the software is given.
- *
- * This software is provided as is without any guarantees or warranty. Although
- * the author has attempted to find and correct any bugs in the software, he
- * is not responsible for any damage caused by the use of the software. The
- * author is under no obligation to provide service, corrections, or upgrades
- * to this package.
- *
- * Despite all the legal stuff above, if you do find bugs, I would like to hear
- * about them. Also, if you have any comments or questions, you may contact me
- * at the following address:
- *
- * David Buck
- * 22C Sonnet Cres.
- * Nepean Ontario
- * Canada, K2H 8W7
- *
- * I can also be reached on the following bulleton boards:
- *
- * OMX (613) 731-3419
- * Mystic (613) 596-4249 or (613) 596-4772
- *
- * Fidonet: 1:163/109.9
- * Internet: dbuck@ccs.carleton.ca
- * The "You Can Call Me RAY" BBS (708) 358-5611
- *
- * IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
- *
- * The "You Can Call Me RAY" BBS (708) 358-5611
- * The Information Exchange BBS (708) 945-5575
- *
- *****************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h> /* contains "malloc" and "exit" prototypes */
- #include <string.h>
-
- #define DBL double
-
- typedef struct {
- unsigned short Red, Green, Blue, Alpha;
- } IMAGE_COLOUR;
-
- IMAGE_COLOUR *iff_colour_map;
- int colourmap_size;
- FILE *f, *out, *out2, *texture_file;
-
- struct Chunk_Header_Struct {
- long name;
- long size;
- };
-
- typedef struct Chunk_Header_Struct CHUNK_HEADER;
-
- static CHUNK_HEADER Chunk_Header;
-
-
- /* function prototypes */
-
- /* char *malloc(unsigned int size); (defined in stdlib.h) */
- void read_iff_file(void);
- void close_all(void);
- void add_texture(unsigned int, unsigned int, unsigned int, unsigned int);
- void iff_error (void);
- int read_byte (FILE *);
- int read_word (FILE *);
- long read_long (FILE *);
- void Read_Chunk_Header (FILE *, CHUNK_HEADER *);
-
-
- DBL *vertices_x, *vertices_y, *vertices_z;
- DBL max_x, max_y, max_z, min_x, min_y, min_z;
- #define FABS(x) ((x<0.0)?-x:x)
-
- #define FORM 0x464f524dL
- #define SC3D 0x53433344L
- #define VERT 0x56455254L
- #define FACE 0x46414345L
-
- #define CMPNONE 0
-
- char *Textures[7] = {"Dull", "Shiny", "Mirror", "Luminous", "Glass", "Metal", "Glass2"};
-
- #define TEXTURE_TABLE_SIZE 16300
- unsigned long *texture_table;
- unsigned int texture_table_size = 0;
-
- char outfile[80];
-
- void close_all()
- {
- if (out != NULL) {
- fclose (out);
- unlink ("triangle.tmp");
- }
-
- if (out2 != NULL) {
- fclose (out2);
- unlink (outfile);
- }
-
- if (texture_file != NULL) {
- fclose (texture_file);
- unlink ("textures.tmp");
- }
-
- if (f != NULL) {
- fclose (f);
- }
- }
-
- void add_texture (texture, red, green, blue)
- unsigned int texture, red, green, blue;
- {
- unsigned long texture_id;
- int i;
-
- texture_id = ((unsigned long)texture << 24) | ((unsigned long)red << 16) | (green << 8) | blue;
-
- for (i = 0; (unsigned) i < texture_table_size; i++)
- if (texture_id == texture_table[i])
- return;
-
- texture_table[texture_table_size++] = texture_id;
-
- if (texture_table_size >= TEXTURE_TABLE_SIZE) {
- fprintf (stderr, "Colour table overflow\n");
- close_all();
- exit(1);
- }
-
- fprintf (texture_file, "DECLARE %s_%d_%d_%d = TEXTURE %s COLOUR RED %f GREEN %f BLUE %f END_TEXTURE\n",
- Textures[texture], red, green, blue,
- Textures[texture], red/255.0, green/255.0, blue/255.0);
- }
-
- void iff_error ()
- {
- fprintf (stderr, "Invalid iff file\n");
- close_all();
- exit(1);
- }
-
- int read_byte(f)
- FILE *f;
- {
- int c;
- if ((c = getc(f)) == EOF)
- iff_error();
- return (c);
- }
-
- int read_word(f)
- FILE *f;
- {
- int result;
-
- result = read_byte(f)*256;
- result += read_byte(f);
- return (result);
- }
-
- long read_long(f)
- FILE *f;
- {
- int i;
- long result;
-
- result = 0;
- for (i = 0 ; i < 4 ; i++)
- result = result * 256 + read_byte(f);
-
- return (result);
- }
-
- void Read_Chunk_Header (f, dest)
- FILE *f;
- CHUNK_HEADER *dest;
- {
- dest->name = read_long(f);
- dest->size = (int) read_long(f);
- }
-
- void read_iff_file()
- {
- int i;
- int vert1, vert2, vert3;
- unsigned int texture;
- unsigned int red_int, green_int, blue_int;
-
- max_x = max_y = max_z = -10000000.0;
- min_x = min_y = min_z = 10000000.0;
-
- while (1) {
- Read_Chunk_Header(f, &Chunk_Header);
- switch ((int) Chunk_Header.name) {
- case FORM: if (read_long(f) != SC3D)
- iff_error();
- break;
-
- case VERT:
- if ((vertices_x = (DBL *)
- malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) {
- fprintf (stderr, "Cannot allocate memory for vertices_x array\n");
- close_all();
- exit(1);
- }
- if ((vertices_y = (DBL *)
- malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) {
- fprintf (stderr, "Cannot allocate memory for vertices_y array\n");
- close_all();
- exit(1);
- }
- if ((vertices_z = (DBL *)
- malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) {
- fprintf (stderr, "Cannot allocate memory for vertices_z array\n");
- close_all();
- exit(1);
- }
- for (i = 0 ; (long) i < Chunk_Header.size/12L ; i++) {
- vertices_x[i] = read_long(f) / 10000.0;
- if (vertices_x[i] < min_x)
- min_x = vertices_x[i];
- if (vertices_x[i] > max_x)
- max_x = vertices_x[i];
-
- vertices_y[i] = read_long(f) / 10000.0;
- if (vertices_y[i] < min_y)
- min_y = vertices_y[i];
- if (vertices_y[i] > max_y)
- max_y = vertices_y[i];
-
- vertices_z[i] = read_long(f) / 10000.0;
- if (vertices_z[i] < min_z)
- min_z = vertices_z[i];
- if (vertices_z[i] > max_z)
- max_z = vertices_z[i];
- }
- break;
-
- case FACE: for (i = 0 ; (long) i < Chunk_Header.size/16L ; i++) {
- vert1 = (int) read_long(f);
- vert2 = (int) read_long(f);
- vert3 = (int) read_long(f);
- red_int = read_byte(f);
- green_int = read_byte(f);
- blue_int = read_byte(f);
-
- texture = read_byte(f);
- texture &= 0x07; /* mask upper bits */
- add_texture (texture, red_int, green_int, blue_int);
-
- fprintf (out, "TRIANGLE <%f %f %f> <%f %f %f> <%f %f %f> TEXTURE %s_%d_%d_%d END_TEXTURE END_TRIANGLE\n",
- vertices_x[vert1], vertices_y[vert1], vertices_z[vert1],
- vertices_x[vert2], vertices_y[vert2], vertices_z[vert2],
- vertices_x[vert3], vertices_y[vert3], vertices_z[vert3],
- Textures[texture], red_int, green_int, blue_int);
- }
- return;
-
- default:
- for (i = 0 ; (long) i < Chunk_Header.size ; i++)
- if (getc(f) == EOF)
- iff_error();
- break;
- }
- }
- }
-
- void main (argc, argv)
- int argc;
- char **argv;
- {
- int c;
-
- if (argc != 3) {
- fprintf (stderr, "Usage: %s <scene-file> <output-file>\n", argv[0]);
- exit (1);
- }
-
- f = out = out2 = texture_file = NULL;
-
- strcpy(outfile, argv[2]);
-
- if ((texture_table = (unsigned long *) malloc((unsigned int)TEXTURE_TABLE_SIZE * sizeof (unsigned long))) == NULL) {
- fprintf (stderr, "Cannot allocate memory for texture table\n");
- exit(1);
- }
-
- if ((f = fopen(argv[1], "rb")) == NULL) {
- fprintf (stderr, "Cannot open IFF file %s\n", argv[1]);
- exit(1);
- }
-
- if ((out = fopen("triangle.tmp", "w")) == NULL) {
- fprintf (stderr, "Cannot open temporary file triangle.tmp\n");
- close_all();
- exit(1);
- }
-
- if ((texture_file = fopen("textures.tmp", "w")) == NULL) {
- fprintf (stderr, "Cannot open temporary file textures.tmp\n");
- close_all();
- exit(1);
- }
-
- fprintf(out, "\nOBJECT\n UNION\n");
- read_iff_file();
- fprintf(out, " END_UNION\n");
- fprintf(out, " BOUNDED_BY\n INTERSECTION\n");
- fprintf(out, " PLANE <1.0 0.0 0.0> %1.02f END_PLANE\n", FABS(max_x) * 1.01);
- fprintf(out, " PLANE <-1.0 0.0 0.0> %1.02f END_PLANE\n", FABS(min_x) * 1.01);
- fprintf(out, " PLANE <0.0 1.0 0.0> %1.02f END_PLANE\n", FABS(max_y) * 1.01);
- fprintf(out, " PLANE <0.0 -1.0 0.0> %1.02f END_PLANE\n", FABS(min_y) * 1.01);
- fprintf(out, " PLANE <0.0 0.0 1.0> %1.02f END_PLANE\n", FABS(max_z) * 1.01);
- fprintf(out, " PLANE <0.0 0.0 -1.0> %1.02f END_PLANE\n", FABS(min_z) * 1.01);
- fprintf(out, " END_INTERSECTION\n END_BOUND\n \nEND_OBJECT\n");
- printf ("X values range from %f to %f\n", min_x, max_x);
- printf ("Y values range from %f to %f\n", min_y, max_y);
- printf ("Z values range from %f to %f\n", min_z, max_z);
- fclose(f);
- fflush(out);
- fclose(out);
- fflush(texture_file);
- fclose(texture_file);
-
- if ((out2 = fopen (argv[2], "w")) == NULL) {
- fprintf (stderr, "Cannot open output file %s\n", argv[2]);
- exit(1);
- }
-
- if ((out = fopen("triangle.tmp", "r")) == NULL) {
- fprintf (stderr, "Cannot open temporary file triangle.tmp\n");
- close_all();
- exit(1);
- }
-
- if ((texture_file = fopen("textures.tmp", "r")) == NULL) {
- fprintf (stderr, "Cannot open temporary file textures.tmp\n");
- close_all();
- exit(1);
- }
-
- while ((c = getc(texture_file)) != EOF)
- putc (c, out2);
-
- while ((c = getc(out)) != EOF)
- putc (c, out2);
-
- fflush(out2);
- fclose(out2);
- out2 = NULL; /* make sure close_all doesn't delete out2 file */
- close_all();
- exit(0);
- }
-